package com.chenfan.magic.tags.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.chenfan.magic.base.Kv;
import com.chenfan.magic.constant.RuntimeConstant;
import com.chenfan.magic.core.IdcEngineEntry;
import com.chenfan.magic.entity.MQLModel;
import com.chenfan.magic.entity.TTLDetailModel;
import com.chenfan.magic.entity.TTLModel;
import com.chenfan.magic.interpreter.ShellInterpreter;
import com.chenfan.magic.resolver._MainResolver;
import com.chenfan.magic.tags.TagShell;
import com.chenfan.magic.utils.FastJsonKit;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * template 标签处理器
 *
 * @author  周夕
 * @date 2020-02-26 18:21
 */
@Component
@AllArgsConstructor
public class TagShellHandler {

    private ShellInterpreter shellInterpreter;


    /**
     * 执行入口
     *
     * @param mqlModel
     * @param key
     * @return
     */
    public boolean execute(
            MQLModel mqlModel,
            Map<String, Object> idcRuntimePool,
            String key,
            Map<String, Object> paramMap,
            Map<String, Object> resMap,
            Map<String, Object> eofMap,
            Map<String, Object> resolveMap,
            Map<String, Object> attributeMap,
            Kv kv,
            TTLModel ttlModel
    ) {
        TTLDetailModel ttlDetailModel = new TTLDetailModel();
        String prefixKey = TagShell.tagNames + "#" + key;
        ttlDetailModel.start(prefixKey);
        TagShell shellModel = mqlModel.getShell(key, idcRuntimePool, paramMap, attributeMap);
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_PREFIXKEY, prefixKey);
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_RESPOND, shellModel.getRespond());
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_RESULTKEY, shellModel.getResultKey());
        Map<String, Object> res = Maps.newHashMap();
        //防止引用检测
        String json = JSON.toJSONString(paramMap, SerializerFeature.DisableCircularReferenceDetect);
        Map<String, Object> pm = FastJsonKit.jsonstring2Map(json);
        pm.remove("#params");
        pm.remove("#context");
        res = run(idcRuntimePool, ttlModel, prefixKey, shellModel, paramMap);
        res.put("#params", pm);
        resMap.put(prefixKey, res);
        paramMap.putAll(attributeMap);
        paramMap.putAll(res);
        resolveMap.put(shellModel.getResultKey(), shellModel.getContext());

        ttlModel.getExecuter().put(ttlDetailModel.end());
        return true;
    }

    /**
     * command指令集动态调度器
     *
     * @param shellModel
     * @param paramMap
     * @return
     */
    public Map<String, Object> run(Map<String, Object> idcRuntimePool, TTLModel ttlModel, String prefixKey, TagShell shellModel, Map<String, Object> paramMap) {
        Map<String, Object> res = Maps.newHashMap();
        String code = new _MainResolver().resolveScope(idcRuntimePool, ttlModel, prefixKey, shellModel, paramMap);
        try {
            res.put("#context", code);
            res.put(shellModel.getResultKey(), shellInterpreter.run(idcRuntimePool, code, ""));
        } catch (Exception e) {
            e.printStackTrace();
            IdcEngineEntry.throwException(idcRuntimePool, null, "shell动态脚本调度器执行异常! \n", e);
        }
        return res;
    }
}
